package com.h2n.utils;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.log4j.Logger;

import java.util.Map;
import java.util.HashMap;
import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * Created by IntelliJ IDEA.
 * User: NhatNV
 * Date: Jul 30, 2009
 * Time: 2:50:16 AM
 * To change this template use File | Settings | File Templates.
 */
public class PropertiesFile extends PropertiesConfiguration {
  private static Logger logger = Logger.getLogger(PropertiesFile.class);
  private static final String[] SEARCH_PATH = {
      "/", ""
  };
  private static final String PROPS_RESOURCE_DEFAULT = "config.properties";
  private static Map instances = new HashMap();
  private String propsFile = PROPS_RESOURCE_DEFAULT;

  public PropertiesFile() {
  }

  public PropertiesFile(String propsFileName) {
    loadProperties(propsFileName);
  }

  /**
   * Load the engine properties. This method searches for the properties resource
   * in a number of places and uses the <code>Class.getResourceAsStream</code>
   * and the <code>Properties.load</code> method to load them.
   */
  public void loadProperties() {
    loadProperties(PROPS_RESOURCE_DEFAULT);
  }

  public void loadProperties(String propsFileName) {
    try {
      if (propsFileName == null || propsFileName.equals("")) propsFileName = PROPS_RESOURCE_DEFAULT;
      File is = null;
      Class c = getClass();
      URL url;
      for (int i = 0; i < SEARCH_PATH.length && is == null; i++) {
        propsFile = SEARCH_PATH[i] + propsFileName;
        url = c.getResource(propsFile);
        if (url != null) is = new File(url.getFile());
//        logger.debug("is="+is);
      }

      if (is != null) {
//        logger.info("Load property file from:"+is.getAbsolutePath());
        loadProperties(is);
      } else {
//        logger.warn("Could not find API properties to load: " + propsFileName);
      }

    } catch (Exception ioe) {
//      logger.error("Could not load engine properties", ioe);
    }
  }

  /**
   * Load the properties from a stream. This method actually just calls
   * <code>Properties.load</code> but includes some useful debugging output
   * too.
   *
   * @param is File
   * @throws java.io.IOException
   */
  public void loadProperties(File is)
      throws IOException {
    try {
      this.setFile(is);
      this.setReloadingStrategy(new FileChangedReloadingStrategy());
      this.setAutoSave(true);

      this.load();

//      logger.info("Loaded engine properties from " + propsFile);
    } catch (Exception e) {
      e.printStackTrace();
      throw new IOException("Failed to load properties from " + propsFile);
    }
  }

  /**
   * Get the singleton <code>PropsConfiguration</code> instance.
   *
   * @return PropsConfiguration
   */
  public static final PropertiesFile getInstance() {
    return getInstance(PROPS_RESOURCE_DEFAULT);
  }

  public static final PropertiesFile getInstance(String propsFileName) {
    PropertiesFile instance;
    if (instances.containsKey(propsFileName)) {
      instance = (PropertiesFile) instances.get(propsFileName);
    } else {
      instance = new PropertiesFile(propsFileName);
      instances.put(propsFileName, instance);
    }
    return instance;
  }

  public String getStringUTF8(String property) {
    return getStringUTF8(property, null);
  }

  public String getStringUTF8(String property, String defaultValue) {
    String value = getString(property);
    try {
      if (value != null) {
        return new String(value.getBytes("ISO-8859-1"), "UTF-8");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    
    return defaultValue;
  }
  
  public String[] getStringArrayUTF8(String property) {
    String[] result = null;
    try {
      String[] values = getStringArray(property);
      if (values != null) {
        result = new String[values.length];
        for (int i = 0; i < values.length; i++) {
          result[i] = new String(values[i].getBytes("ISO-8859-1"), "UTF-8");
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    
    return result;
  }
}
